﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using GalaSoft.MvvmLight;
using TinyEngine.Editor.Extensibility;
using GalaSoft.MvvmLight.Command;
using System.IO;

namespace TinyEngineEditor.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        #region Commands
        RelayCommand _newCommand;
        public RelayCommand NewCommand
        {
            get
            {
                return _newCommand ?? (_newCommand =
                    new RelayCommand(() => this.NewInstance()));
            }
        }

        RelayCommand _openCommand;
        public RelayCommand OpenCommand
        {
            get
            {
                return _openCommand ?? (_openCommand =
                    new RelayCommand(() => this.OpenInstance()));
            }
        }

        private bool _canOpenScene;
        public bool CanOpenScene
        {
            get { return _canOpenScene; }
            set
            {
                if (_canOpenScene == value)
                    return;

                var oldValue = _canOpenScene;
                _canOpenScene = value;
                OpenSceneCommand.RaiseCanExecuteChanged();
                RaisePropertyChanged("CanOpenScene", oldValue, CanOpenScene, true);
            }
        }

        RelayCommand _openSceneCommand;
        public RelayCommand OpenSceneCommand
        {
            get
            {
                return _openSceneCommand ?? (_openSceneCommand =
                    new RelayCommand(() => this.OpenScene(), () => this.CanOpenScene));
            }
        }

        private bool _canSave;
        public bool CanSave
        {
            get { return _canSave; }
            set
            {
                if (_canSave == value)
                    return;

                var oldValue = _canSave;
                _canSave = value;
                SaveCommand.RaiseCanExecuteChanged();
                RaisePropertyChanged("CanSave", oldValue, CanSave, true);
            }
        }

        RelayCommand _saveCommand;
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand ?? (_saveCommand =
                    new RelayCommand(() => this.SaveInstance(), () => this.CanSave));
            }
        }

        private bool _canClose;
        public bool CanClose
        {
            get { return _canClose; }
            set
            {
                if (_canClose == value)
                    return;

                var oldValue = _canClose;
                _canClose = value;
                CloseCommand.RaiseCanExecuteChanged();
                RaisePropertyChanged("CanClose", oldValue, CanClose, true);
            }
        }

        RelayCommand _closeCommand;
        public RelayCommand CloseCommand
        {
            get
            {
                return _closeCommand ?? (_closeCommand =
                    new RelayCommand(() => this.CloseInstance(), () => this.CanClose));
            }
        }
        #endregion

        #region Properties
        #endregion
        public event PropertyChangedEventHandler PropertyChanged;
        public MainViewModel()
        {
            EditorSession.Instance.ProjectLoaded += new Action(Instance_ProjectLoaded);
            EditorSession.Instance.SceneLoaded += new Action<TinyEngine.Core.Scene.TinyScene>(Instance_SceneLoaded);
        }

        void Instance_SceneLoaded(TinyEngine.Core.Scene.TinyScene obj)
        {
            NotifyPropChanged("HasSceneOpen");
        }

        void Instance_ProjectLoaded()
        {
            NotifyPropChanged("HasProjectOpen");
            CanClose = true;
            CanSave = true;
            CanOpenScene = true;
        }

        private void NotifyPropChanged(string p)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(p));
        }

        public bool HasProjectOpen
        {
            get
            {
                return EditorSession.Instance != null &&
                    EditorSession.Instance.HasLoadedProject;
            }
        }
        public bool HasSceneOpen
        {
            get { return EditorSession.Instance.HasLoadedScene; }
        }

        internal void ResetAll()
        {
            NotifyPropChanged("HasSceneOpen");
            NotifyPropChanged("HasProjectOpen");
        }

        void NewInstance()
        {

        }

        void OpenInstance()
        {
            var dialog = new Microsoft.Win32.OpenFileDialog
            {
                AddExtension = true,
                //FileName = initialFileName,
                ValidateNames = true,
                DefaultExt = ".tproj",
                //InitialDirectory = initialDirectory,
                Filter = "Tiny Project Files(*.tproj)|*.tproj|All Files (*.*)|*.*",
                Title = "Select TinyEngine Project file to Open"
            };
            if (dialog.ShowDialog() == true)
            {
                if (!string.IsNullOrEmpty(dialog.FileName))
                {
                    EditorSession.Instance.LoadProject(dialog.FileName);
                    // HACK: Use an IsDirty bit that detects when the in-memory object differs from the File
                    CanSave = true;
                }
            }
        }

        void OpenScene()
        {
            var initialDirectory = Path.Combine(EditorSession.Instance.RootPath, EditorSession.Instance.ActiveProject.ContentPath);
            initialDirectory = Path.GetFullPath(initialDirectory);
            var dialog = new Microsoft.Win32.OpenFileDialog
            {
                AddExtension = true,
                //FileName = initialFileName,
                ValidateNames = true,
                DefaultExt = ".scene",
                InitialDirectory = initialDirectory,
                Filter = "Tiny Scene Files(*.scene)|*.scene|All Files (*.*)|*.*",
                Title = "Select TinyEngine Scene file to Open"
            };
            if (dialog.ShowDialog() == true)
            {
                if (!string.IsNullOrEmpty(dialog.FileName))
                    EditorSession.Instance.LoadScene(dialog.FileName);
            }
        }

        void SaveInstance()
        {
            // HACK: Why not do the null check in SaveAll? If you can bury a null check, do it -JB
            if (EditorSession.Instance.ActiveProject != null)
                EditorSession.SaveAll();
        }

        void CloseInstance()
        {
            EditorSession.Instance.CloseAll();
            ResetAll();
        }

        public override void Cleanup()
        {
            // Clean up if needed

            base.Cleanup();
        }
    }
}
